#ifndef CSNODE_H
#define CSNODE_H

#include "config.h"
#include "csobj.h"

/**
 * Desc: 用来计算和管理一个发射器或者激光发射出来的元素的东西
 * Auth: 张宇飞
 * Date: 2014-08-25
 */

#ifdef __cplusplus
extern "C" {
#endif

/*********************| 一些宏 |*********************/

#define NODE_CTL_NONE		0	// 没有任何控制
#define NODE_CTL_STOP_EMIT	0x1	// 停止自动发射控制
#define NODE_CTL_STOP_OBJ	0x2	// 停止obj对象的刷新
#define NODE_CTL_STOP_BULLET	0x4	// 停止刷新bullet

/**
 * 计算n个炮口的范围为range角度数的，每个炮口角度偏移为angle的，
 * 第x个炮口的发射角度
 * n为正整数,0 <= range <= 360 *n , 0 <= angle <= 360 * n,
 * 0 < x < n
 */
#define emit_angle(n, range, angle, x)	((x + 0.5) * (range / n) + angle)

// buupdate_cb_fun 的返回值控制意义
#define	BULLET_UPDATE_PAUSE	0
#define	BULLET_UPDATE_CONTINUE	1
#define	BULLET_UPDATE_DEAD	2
/*********************| 结构定义 |*********************/
typedef struct csnode_t csnode_t;
typedef void (*node_cb_fun)(csnode_t*, void*);
typedef void (*obj_cb_fun)(csobj_t*, void*);
typedef void (*bullet_cb_fun)(bullet_t*, void*);
typedef int (*buupdate_cb_fun)(bullet_t*, void*);
typedef void (*automachine_fun)(pos_t*, void*);

struct node_cb_t{
	node_cb_fun	on_begin;     // 准备好一些事项
	node_cb_fun	on_end;       // 清除一些内存
#ifdef CSNODE_ENALBE_ONFRAME_CALL
	node_cb_fun	on_frame;     // 如果需要的话再开启每一帧都调用的
#endif
	obj_cb_fun	on_objupdate; // 发射器刷新
	bullet_cb_fun	on_buborn;    // 在子弹出生时,触发发射动画，或者产生淡入动画
	bullet_cb_fun	on_budead;    // 在子弹消亡前,消除子弹精灵，触发消除动画
	buupdate_cb_fun	on_buupdate;  // 子弹刷新
	automachine_fun on_am;	      // 自机狙
	pos_t		autoPos;      // 自机狙位置
	void*		udata;        // 用户数据自定义数据(C++绑定可用)
	// TODO:也许还要事件触发接口等等
} ;

struct csnode_t{
	csobjdata_t*	pobjdata;//用于计算的模板
	csobj_t*	pobj;	// 用于显示的
	list_t		bulist; // 子弹
	size_t		nframe;	// 用于刷新计算时间的单位
	size_t		nextEm; //下一次发射时间
	node_cb_t	cbs;	// 一大把回调
	int		ctlflag;// 控制位(可以给绑定等等使用)
};

/*********************| 外部接口 |*********************/
/* 初始化一个计算节点 */
extern CSB_DLL void		csnode_buf_init();
extern CSB_DLL void		csnode_buf_end(bool force);
extern CSB_DLL csnode_t*	csnode_buf_rent(csobjdata_t* pobjdata, const node_cb_t* pcb,
					    const int ctl);
extern CSB_DLL void		csnode_zero_bulist(csnode_t* pnode);
extern CSB_DLL void		csnode_buf_return(csnode_t* pnode);
/* 进行一次状态更新运算 */
extern CSB_DLL void		csnode_update(csnode_t* pcsnode);
/* 立即进行一次发射 */
extern CSB_DLL void		csnode_emit_bullet(csnode_t* pcsn);
/* 根据元素内部属性进行属性的变化 */
extern CSB_DLL void		csnode_update_obj(csnode_t* pcsn);


#ifdef __cplusplus
} /* end extern C */
#endif

#endif // CSNODE_H
